package v1

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"strings"

	"github.com/gin-gonic/gin"

	bc "application/blockchain"
	"application/global"
	"application/model"
)

type UserInfo struct {
	OpenId   string `json:"openid"`
	NickName string `json:"nickname"`
}
type GetAccountId struct {
	AccountId string `json:"accountId"`
}
type T struct {
	Ret             int    `json:"ret"`
	Msg             string `json:"msg"`
	IsLost          int    `json:"is_lost"`
	Nickname        string `json:"nickname"`
	Gender          string `json:"gender"`
	GenderType      int    `json:"gender_type"`
	Province        string `json:"province"`
	City            string `json:"city"`
	Year            string `json:"year"`
	Figureurl       string `json:"figureurl"`
	Figureurl1      string `json:"figureurl_1"`
	Figureurl2      string `json:"figureurl_2"`
	FigureurlQq1    string `json:"figureurl_qq_1"`
	FigureurlQq2    string `json:"figureurl_qq_2"`
	FigureurlQq     string `json:"figureurl_qq"`
	IsYellowVip     string `json:"is_yellow_vip"`
	Vip             string `json:"vip"`
	YellowVipLevel  string `json:"yellow_vip_level"`
	Level           string `json:"level"`
	IsYellowYearVip string `json:"is_yellow_year_vip"`
}

var User = UserInfo{}

func GetAuthCode(w http.ResponseWriter, r *http.Request) string {
	params := url.Values{}
	params.Add("response_type", "code")
	params.Add("client_id", global.AppId)
	params.Add("state", "test")
	str := fmt.Sprintf("%s&redirect_uri=%s", params.Encode(), global.RedirectURI)
	loginURL := fmt.Sprintf("%s?%s", "https://graph.qq.com/oauth2.0/authorize", str)
	fmt.Println("loginURL:", loginURL)
	return loginURL
}

func GetToken(w http.ResponseWriter, r *http.Request) {
	code := r.FormValue("code")
	params := url.Values{}
	params.Add("grant_type", "authorization_code")
	params.Add("client_id", global.AppId)
	params.Add("client_secret", global.AppKey)
	params.Add("code", code)
	str := fmt.Sprintf("%s&redirect_uri=%s", params.Encode(), global.RedirectURI)
	fmt.Println("str:", str)
	loginURL := fmt.Sprintf("%s?%s", "https://graph.qq.com/oauth2.0/token", str)

	response, err := http.Get(loginURL)
	if err != nil {
		w.Write([]byte(err.Error()))
	}
	defer response.Body.Close()

	bs, _ := ioutil.ReadAll(response.Body)
	body := string(bs)

	resultMap := convertToMap(body)

	info := &global.PrivateInfo{}
	info.AccessToken = resultMap["access_token"]
	info.RefreshToken = resultMap["refresh_token"]
	info.ExpiresIn = resultMap["expires_in"]

	GetOpenId(info, w, r)
}

func GetOpenId(info *global.PrivateInfo, w http.ResponseWriter, r *http.Request) {
	resp, err := http.Get(fmt.Sprintf("%s?access_token=%s", "https://graph.qq.com/oauth2.0/me", info.AccessToken))
	if err != nil {
		w.Write([]byte(err.Error()))
	}
	defer resp.Body.Close()

	bs, _ := ioutil.ReadAll(resp.Body)
	body := string(bs)
	info.OpenId = body[45:77]
	GetUserInfo(info, w, r)
	fmt.Println("info_id", info.OpenId)
}

// 4. Get User info
func GetUserInfo(info *global.PrivateInfo, w http.ResponseWriter, r *http.Request) {
	params := url.Values{}
	params.Add("access_token", info.AccessToken)
	params.Add("openid", info.OpenId)
	params.Add("oauth_consumer_key", global.AppId)

	uri := fmt.Sprintf("https://graph.qq.com/user/get_user_info?%s", params.Encode())
	resp, err := http.Get(uri)
	if err != nil {
		w.Write([]byte(err.Error()))
	}
	defer resp.Body.Close()
	bs, _ := ioutil.ReadAll(resp.Body)
	var ma T
	json.Unmarshal(bs, &ma)
	User.OpenId = info.OpenId
	User.NickName = ma.Nickname

	if AccountId != "" {
		//qq绑定逻辑
		var login model.QQLogin
		result := global.DB.Model(&model.QQLogin{}).Where("open_id=?", User.OpenId).First(&login)
		if result.RowsAffected == 0 {
			fmt.Println("表里边没有这条数据！", result.Error)
			qqLogin := model.QQLogin{
				NickName:  User.NickName,
				OpenId:    User.OpenId,
				AccountId: AccountId,
			}
			result = global.DB.Create(&qqLogin)
			if result.RowsAffected == 0 {
				fmt.Println("openId存储失败！", result.Error)
			}
		}
		http.Redirect(w, r, "http://localhost:9528", http.StatusFound)
	} else {
		//qq绑定逻辑
		var login model.QQLogin
		result := global.DB.Model(&model.QQLogin{}).Where("open_id=?", User.OpenId).First(&login)
		if result.RowsAffected == 0 {
			fmt.Println("表里边没有这条数据！", result.Error)
			qqLogin := model.QQLogin{
				NickName:  User.NickName,
				OpenId:    User.OpenId,
				AccountId: AccountId,
			}
			result = global.DB.Create(&qqLogin)
			if result.RowsAffected == 0 {
				fmt.Println("openId存储失败！", result.Error)
			}
		}
		http.Redirect(w, r, "http://127.0.0.1:9090/qqAdd", http.StatusFound)
	}
}

// GetUserInfos 绑定qq
func GetUserInfos(c *gin.Context) {
	var bodyByte [][]byte
	bodyByte = append(bodyByte, []byte(User.NickName))
	bodyByte = append(bodyByte, []byte(User.OpenId))
	//调用智能合约
	resp, err := bc.ChannelExecute("createMobileUser-key", bodyByte)
	if err != nil {
		c.JSON(400, gin.H{
			"code": 400,
			"msg":  "调用智能合约失败！",
		})
		return
	}
	var data map[string]interface{}
	err = json.Unmarshal(bytes.NewBuffer(resp.Payload).Bytes(), &data)
	if err != nil {
		c.JSON(400, gin.H{
			"code": 400,
			"msg":  "反序列化失败！",
		})
		return
	}
	c.Redirect(302, "http://localhost:9528")
}
func convertToMap(str string) map[string]string {
	var resultMap = make(map[string]string)
	values := strings.Split(str, "&")
	for _, value := range values {
		vs := strings.Split(value, "=")
		resultMap[vs[0]] = vs[1]
	}
	return resultMap
}
